//
//  AppDelegate.m
//  efairy
//
//  Created by XiangDongMBP on 2017/7/7.
//  Copyright © 2017年 East. All rights reserved.
//

#import "AppDelegate.h"
#import "GlobalHeader.h"
#import "EFARootVC.h"
#import "EFALoginVC.h"
#import <Bugly/Bugly.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import "UIColor+XDHex.h"
#import <Highcharts/Highcharts.h>
#import <IQKeyboardManager.h>
#import <SDWebImageManager.h>
#import <SDImageCacheConfig.h>
#import <RongIMLib/RongIMLib.h>
#import "EFAModel.h"
#import <AudioToolbox/AudioToolbox.h>
#import "ApiManager.h"
#import <KSPhotoBrowser.h>
#import "KSSDImageManager.h"
// 引入JPush功能所需头文件
#import <JPUSHService.h>
#import <sqlite3.h>
#import "NSTimer+YYAdd.h"

// iOS10注册APNs所需头文件   个推导入证书密码：modal3\fluid（测试版）
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif




@interface AppDelegate ()<RCIMClientReceiveMessageDelegate, JPUSHRegisterDelegate,PKPushRegistryDelegate,GeTuiSdkDelegate>
@property (nonatomic, assign) NSInteger msgCnt;
@property (nonatomic,assign)  BOOL isExeBadge;
@end
static sqlite3 *database;

@implementation AppDelegate

#pragma mark - life cycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //当应用处于完全退出时，点击接收到的推送消息会启动应用并回调下面的方法：
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    // 初始化Bugly
    [Bugly startWithAppId:EFAGlobalBuglyAppId];
    // 加载本地缓存
    if ([[EFAModel sharedInstance] getFromDisk]) {
        NSLog(@"初始化缓存成功！");
    } else {
        NSLog(@"初始化缓存失败！");
    }
    // 配置全局的界面属性
    [self setGlobalAppearance];
    // 一些初始化信息：IQKeyboardManager、高德地图、HighCharts图表、微信SDK、极光SDK、融云SDK
    [self starupInfoWithOptions:launchOptions application:application];
    
    [self createDB];
    

    
    
    // 初始化RootViewController
//    if ([EFAModel sharedInstance].isNewVersion) {   ///< 进入引导页
//        [self setupWelcomeVC];
//    }
    if ([EFAModel sharedInstance].isLogin) { ///< 进入登录页面
        [self setupRootVC];
    } else {    ///< 进入主页面
        [self setupWelcomeVC];
    }
    [self.window makeKeyAndVisible];
    
    // 请求审核
    [self checkIosReview];
    
    return YES;
}

//个推相关方开始
/** 注册远程通知 */
- (void)registerRemoteNotification {
    /*
     警告：Xcode8的需要手动开启“TARGETS -> Capabilities -> Push Notifications”
     */
    
    /*
     警告：该方法需要开发者自定义，以下代码根据APP支持的iOS系统不同，代码可以对应修改。
     以下为演示代码，注意根据实际需要修改，注意测试支持的iOS系统都能获取到DeviceToken
     */
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8编译会调用
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
            if (!error) {
                NSLog(@"request authorization succeeded!");
            }
        }];

        [[UIApplication sharedApplication] registerForRemoteNotifications];
#else // Xcode 7编译会调用
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
#endif
    } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    } else {
        UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert |
                                                                       UIRemoteNotificationTypeSound |
                                                                       UIRemoteNotificationTypeBadge);
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
    }
}


#pragma mark - 远程通知(推送)回调

///** 远程通知注册成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    // [3]:向个推服务器注册deviceToken 为了方便开发者，建议使用新方法
    [GeTuiSdk registerDeviceTokenData:deviceToken];

    /// 极光推送
    /// Required - 注册 DeviceToken
    [JPUSHService registerDeviceToken:deviceToken];

    NSLog(@"\n>>>[DeviceToken(NSData)]: %@\n\n", deviceToken);
}

/** 远程通知注册失败委托 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"\n>>>[DeviceToken Error]:%@\n\n", error.description);
}

#pragma mark - APP运行中接收到通知(推送)处理 - iOS 10以下版本收到推送
/** APP已经接收到“远程”通知(推送) - 透传推送消息  当应用处于后台时，点击接收到的推送消息会将应用置于前台回调下面的方法，应用处于前台时，不会在状态栏提示接收到的推送消息*/
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    
    // [ GTSdk ]：将收到的APNs信息传给个推统计
    [GeTuiSdk handleRemoteNotification:userInfo];
    
    // Required, iOS 7 Support
    [JPUSHService handleRemoteNotification:userInfo];
    
    // 控制台打印接收APNs信息
    NSLog(@"\n>>>[Receive RemoteNotification]:%@\n\n", userInfo);
    
    completionHandler(UIBackgroundFetchResultNewData);
    
}

#pragma mark - iOS 10中收到推送消息

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
//  iOS 10: App在前台获取到通知
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    
    NSLog(@"willPresentNotification：%@", notification.request.content.userInfo);
    
    // 根据APP需要，判断是否要提示用户Badge、Sound、Alert
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}

//  iOS 10: 点击通知进入App时触发
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    
    NSLog(@"didReceiveNotification：%@", response.notification.request.content.userInfo);
    
    // [ GTSdk ]：将收到的APNs信息传给个推统计
    [GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo];
    
    completionHandler();
}
#endif

#pragma mark - VOIP 接入

/** 注册VOIP服务 */
- (void)voipRegistration {
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    PKPushRegistry *voipRegistry = [[PKPushRegistry alloc] initWithQueue:mainQueue];
    voipRegistry.delegate = self;
    // Set the push type to VoIP
    voipRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}

// 实现 PKPushRegistryDelegate 协议方法

/** 系统返回VOIPToken，并提交个推服务器 */
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
    //向个推服务器注册 VoipToken 为了方便开发者，建议使用新方法
    [GeTuiSdk registerVoipTokenCredentials:credentials.token];
    
    NSLog(@"\n>>[VoipToken(NSData)]: %@", credentials.token);
}

/** 接收VOIP推送中的payload进行业务逻辑处理（一般在这里调起本地通知实现连续响铃、接收视频呼叫请求等操作），并执行个推VOIP回执统计 */
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    //个推VOIP回执统计
    [GeTuiSdk handleVoipNotification:payload.dictionaryPayload];
    
    //TODO:接受VOIP推送中的payload内容进行具体业务逻辑处理
    NSLog(@"[Voip Payload]:%@,%@", payload, payload.dictionaryPayload);
}


#pragma mark - GeTuiSdkDelegate

/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
    // [4-EXT-1]: 个推SDK已注册，返回clientId
    NSLog(@"\n>>[GTSdk RegisterClient]:%@\n\n", clientId);
    
}

/** SDK遇到错误回调 */
- (void)GeTuiSdkDidOccurError:(NSError *)error {
    // [EXT]:个推错误报告，集成步骤发生的任何错误都在这里通知，如果集成后，无法正常收到消息，查看这里的通知。
    NSLog(@"\n>>[GTSdk error]:%@\n\n", [error localizedDescription]);
}


/** SDK收到透传消息回调 */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
    // [ GTSdk ]：汇报个推自定义事件(反馈透传消息)
    [GeTuiSdk sendFeedbackMessage:90001 andTaskId:taskId andMsgId:msgId];
    
    // 数据转换
    NSString *payloadMsg = nil;
    if (payloadData) {
        payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
    }
    
  
    
        //把推送内容转换字典
//        if (payloadMsg != nil) {
//            NSData *jsonData = [payloadMsg dataUsingEncoding:NSUTF8StringEncoding];
//            NSError *err;
//            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
//                                                                options:NSJSONReadingMutableContainers
//                                                                  error:&err];
//        }
    // 控制台打印日志
    NSString *msg = [NSString stringWithFormat:@"taskId=%@,messageId:%@,payloadMsg:%@%@", taskId, msgId, payloadMsg, offLine ? @"<离线消息>" : @""];
    NSLog(@"\n>>[GTSdk ReceivePayload]:%@\n\n", msg);
    if(payloadMsg != nil){
        EFAMsgIMItem *item = [EFAMsgIMItem yy_modelWithJSON:payloadMsg];
        NSInteger userId = [EFAModel sharedInstance].loginInfo.user_info.efairyuser_id;
        item.msgId  = [NSString stringWithFormat:@"%@%ld",item.efairymsg_from_id,userId];
        item.userId = [NSString stringWithFormat:@"%ld",userId];
        long timestamp = [AppDelegate getNowTimeTimestamp];
        item.msgAddTime = timestamp;
        NSDictionary *dicContent = nil;
        if(item.efairymsg_content != nil){
            NSData *mJsonData = [item.efairymsg_content dataUsingEncoding:NSUTF8StringEncoding];
            NSError *mErr;
            dicContent = [NSJSONSerialization JSONObjectWithData:mJsonData options:NSJSONReadingMutableContainers error:&mErr];
        }
        item.efairymsg_content = dicContent != nil?dicContent[@"text"]:item.efairymsg_content;
        [self insertOrUpdate:item];
        
        
       
        [[NSNotificationCenter defaultCenter] postNotificationName:EFAGlobalNotiGETUIDispatchMsg object:item];
        // 本地推送
//        UILocalNotification *localNote = [[UILocalNotification alloc] init];
//        localNote.soundName = UILocalNotificationDefaultSoundName;
//        localNote.fireDate = [NSDate date];
//        localNote.alertBody = [NSString stringWithFormat:@"%@：%@", item.efairydevice_name, item.efairymsg_content];
//        [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
    // 设置角标
        [self setApplicaitonIconBadge];
    }
   
}

/** SDK收到sendMessage消息回调 */
- (void)GeTuiSdkDidSendMessage:(NSString *)messageId result:(int)result {
    // 发送上行消息结果反馈
    NSString *msg = [NSString stringWithFormat:@"sendmessage=%@,result=%d", messageId, result];
    NSLog(@"\n>>[GTSdk DidSendMessage]:%@\n\n", msg);
}

/** SDK运行状态通知 */
- (void)GeTuiSDkDidNotifySdkState:(SdkStatus)aStatus {
    // 通知SDK运行状态
    NSLog(@"\n>>[GTSdk SdkState]:%u\n\n", aStatus);
}

/** SDK设置推送模式回调 */
- (void)GeTuiSdkDidSetPushMode:(BOOL)isModeOff error:(NSError *)error {
    if (error) {
        NSLog(@"\n>>[GTSdk SetModeOff Error]:%@\n\n", [error localizedDescription]);
        return;
    }
    
    NSLog(@"\n>>[GTSdk SetModeOff]:%@\n\n", isModeOff ? @"开启" : @"关闭");
}
//个推相关方法结束



- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    
    //设置角标
//    RCConnectionStatus status = [[RCIMClient sharedRCIMClient] getConnectionStatus];
//    if (status != ConnectionStatus_SignUp) {
//        [self setApplicaitonIconBadge];
//    }
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    
    // 移除电次元业务逻辑通知
    [self removeEfairyNotication];
    // 保存本地数据
    if ([[EFAModel sharedInstance] saveToDisk]) {
        NSLog(@"保存数据到磁盘成功!");
    } else {
        NSLog(@"保存数据到磁盘失败!");
    }
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    
    // 注册电次元业务逻辑通知
    [self addEfairyNotification];
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

/**
 * 推送处理2
 */
//注册用户通知设置
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    // register to receive notifications
    [application registerForRemoteNotifications];
}

/**
 * 推送处理3
 */
//- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//    /// 融云需要推送
//    NSString *rcToken = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<" withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
//    [[RCIMClient sharedRCIMClient] setDeviceToken:rcToken];
//    NSLog(@"注册推送Token = %@", rcToken);
//
//    /// 极光推送
//    /// Required - 注册 DeviceToken
//    [JPUSHService registerDeviceToken:deviceToken];
//}

/** 远程通知注册失败委托 */
//- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//    //Optional
//    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
//}

#pragma mark - JPUSHRegisterDelegate
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
    // Required
    NSDictionary * userInfo = notification.request.content.userInfo;
    NSLog(@"iOS10前台收到推送%@", userInfo);
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法，选择是否提醒用户，有Badge、Sound、Alert三种类型可以选择设置
}

// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
    // Required
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    NSLog(@"iOS10后台收到了推送%@", userInfo);     //!< iOS10本地推送也会走这个接口，那iOS8、iOS9呢？
    // 处理推送
    [self handlePushWithUserInfo:userInfo];
    
    if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        [JPUSHService handleRemoteNotification:userInfo];
    }
    completionHandler();  // 系统要求执行这个方法
}

//- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//    // 处理推送
//    [self handlePushWithUserInfo:userInfo];
//
//    // Required, iOS 7 Support
//    [JPUSHService handleRemoteNotification:userInfo];
//    completionHandler(UIBackgroundFetchResultNewData);
//}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    
    // Required,For systems with less than or equal to iOS6
    [JPUSHService handleRemoteNotification:userInfo];
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    NSLog(@"收到本地推送：%@", notification.userInfo);
    [self handlePushWithUserInfo:notification.userInfo];
}

#pragma mark - RCIMClientReceiveMessageDelegate
- (void)onReceived:(RCMessage *)message left:(int)nLeft object:(id)object {
    // 播放系统提示音
    self.msgCnt++;
    NSLog(@"收到第(%ld)条消息, left=%d", self.msgCnt, nLeft);
    if (nLeft == 0) {
        AudioServicesPlaySystemSound(1007);
        [[NSNotificationCenter defaultCenter] postNotificationName:EFAGlobalNotiRCIMDispatchMsg object:nil userInfo:@{@"left" : @(nLeft)}];
    }
//    NSLog(@"收到消息：(%@), 还剩余的未接收的消息数：%d", message, nLeft);
    if ([[RCIMClient sharedRCIMClient] sdkRunningMode] == RCSDKRunningMode_Background) {
        // 检查是否允许推送
        [[RCIMClient sharedRCIMClient] getNotificationQuietHours:^(NSString *startTime, int spansMin) {
            if (!spansMin) {
                if ([message.content isMemberOfClass:[RCTextMessage class]]) {
                    RCTextMessage *testMessage = (RCTextMessage *)message.content;
                    EFAMsgIMItem *item = [EFAMsgIMItem yy_modelWithJSON:testMessage.extra];
                    // 本地推送
                    UILocalNotification *localNote = [[UILocalNotification alloc] init];
                    localNote.soundName = UILocalNotificationDefaultSoundName;
                    localNote.fireDate = [NSDate date];
                    localNote.alertBody = [NSString stringWithFormat:@"%@：%@", item.efairydevice_name, testMessage.content];
                    [[UIApplication sharedApplication] scheduleLocalNotification:localNote];
                }
                // 设置角标
                if (nLeft == 0) {
                    [self setApplicaitonIconBadge];
                }
            }
        } error:nil];
    }
}

#pragma mark - 通知相关
- (void)addEfairyNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenInvalidHandle:) name:EFAGlobalNotiUserTokenInvalid object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutHandle:) name:EFAGlobalNotiLogout object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginRootVCHandle:) name:EFAGlobalNotiLoginRootVC object:nil];
}

- (void)removeEfairyNotication {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:EFAGlobalNotiUserTokenInvalid object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:EFAGlobalNotiLogout object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:EFAGlobalNotiLoginRootVC object:nil];
}

- (void)tokenInvalidHandle:(NSNotification *)notification {
    if ([self.window.rootViewController isKindOfClass:[UINavigationController class]]) {
        return;
    }
    
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"请重新登录" message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alertVC addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [[EFAModel sharedInstance] logout];
//        [self jumpToLoginVC];
        [self jumpToWelcomeVC];
    }]];
    [self.window.rootViewController presentViewController:alertVC animated:YES completion:nil];
}
- (void)logoutHandle:(NSNotification *)notification {
    [[EFAModel sharedInstance] logout];
//    [self jumpToLoginVC];
    [self jumpToWelcomeVC];
}
- (void)loginRootVCHandle:(NSNotification *)notification {
    [self jumpToRootVC];
}
#pragma mark - private methods
- (void)jumpToLoginVC {
    [self setupLoginVC];
    //转场动画
    CATransition *anim = [CATransition animation];
    //    anim.type = @"rippleEffect";
    anim.type = @"moveIn";
    anim.subtype = @"fromRight";
    anim.duration = 0.5;
    [self.window.layer addAnimation:anim forKey:nil];
}
- (void)jumpToWelcomeVC {
    [self setupWelcomeVC];
    //转场动画
    CATransition *anim = [CATransition animation];
    anim.type = @"fade";
    anim.duration = 0.5;
    [[UIApplication sharedApplication].keyWindow.layer addAnimation:anim forKey:nil];
}
- (void)jumpToRootVC {
    [self setupRootVC];
    //转场动画
    CATransition *anim = [CATransition animation];
    anim.type = @"fade";
    anim.duration = 0.5;
    [[UIApplication sharedApplication].keyWindow.layer addAnimation:anim forKey:nil];
}
- (void)setupWelcomeVC {
    UIStoryboard *mainSb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *loginNavC = [mainSb instantiateViewControllerWithIdentifier:@"EFAWelcomPVC"];
    [self.window setRootViewController:loginNavC];
}
- (void)setupRootVC {
    EFARootVC *rootVC = [[EFARootVC alloc] init];
    [self.window setRootViewController:rootVC];
}
- (void)setupLoginVC {
    UIStoryboard *mainSb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UIViewController *loginNavC = [mainSb instantiateViewControllerWithIdentifier:@"EFALoginNavC"];
    [self.window setRootViewController:loginNavC];
}
- (void)setApplicaitonIconBadge {
    if(_isExeBadge || ![EFAModel sharedInstance].isLogin){
        return;
    }
    _isExeBadge = YES;
    [NSTimer scheduledTimerWithTimeInterval:3.0f block:^(NSTimer * _Nonnull timer) {
        int unreadMsgCount = [self getNotReadMsgNum];
        if(unreadMsgCount > 1000){
            unreadMsgCount = 1000;
        }
//         AudioServicesPlaySystemSound(1007);
        [UIApplication sharedApplication].applicationIconBadgeNumber = unreadMsgCount;
        _isExeBadge = NO;
    } repeats:NO];
}

#pragma mark - 全局页面属性设置
//全局设置导航栏的颜色，TabBar的颜色
- (void)setGlobalAppearance {
    //UINavigationBar
    UINavigationBar *navBar = [UINavigationBar appearance];
    [navBar setBarTintColor:[UIColor whiteColor]];
    [navBar setTintColor:[UIColor xd_colorWithHex:EFAGlobalColorFontLightBlack]];
    NSDictionary *textAttributes = @{NSForegroundColorAttributeName: [UIColor xd_colorWithHex:EFAGlobalColorFontDarkBlack],
                                     NSFontAttributeName: [UIFont systemFontOfSize:18]};
    [navBar setTitleTextAttributes:textAttributes];
    
    //    navBar.backIndicatorImage = [UIImage imageNamed:@"global_nav_back"];
    //    navBar.backIndicatorTransitionMaskImage = [UIImage imageNamed:@"global_nav_back"];
    
    if (@available(iOS 11.0, *)) {
        ;
    } else {
        // 返回的图片
        UIImage *backImg = [UIImage imageNamed:@"global_nav_back"];
        [[UIBarButtonItem appearance] setBackButtonBackgroundImage:backImg
                                                          forState:UIControlStateNormal
                                                        barMetrics:UIBarMetricsDefault];
    }
    
    //UIBarButtonItem
    NSDictionary * barItemAttributes = @{NSForegroundColorAttributeName: [UIColor xd_colorWithHex:EFAGlobalColorFontLightBlack],
                                         NSFontAttributeName: [UIFont systemFontOfSize:15]};
    [[UIBarButtonItem appearance] setTitleTextAttributes:barItemAttributes forState:UIControlStateNormal];
    
    //TabBar
    [[UITabBar appearance] setTintColor:[UIColor xd_colorWithHex:EFAGlobalColorDarkGreen]];
    [[UITabBar appearance] setBarTintColor:[UIColor whiteColor]];
    NSDictionary * itemAttributes = @{NSFontAttributeName: [UIFont systemFontOfSize:10]};
    [[UIBarItem appearance] setTitleTextAttributes:itemAttributes forState:UIControlStateNormal];
}

- (void)starupInfoWithOptions:(NSDictionary *)launchOptions application:(UIApplication *)application {
    // AFNetworking
//    [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    
    // 键盘的全局隐藏
    [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
    [IQKeyboardManager sharedManager].shouldResignOnTouchOutside = YES;
//    // 特定界面禁止
//    [[IQKeyboardManager sharedManager].disabledDistanceHandlingClasses addObject:[KABCosplayDetailVC class]];
//    [[IQKeyboardManager sharedManager].disabledDistanceHandlingClasses addObject:[KABCosplayReplyVC class]];
//    [[IQKeyboardManager sharedManager].disabledDistanceHandlingClasses addObject:[RCConversationViewController class]];
    
//    // SDWebImage设置缓存
//    SDImageCache *cache = [SDWebImageManager sharedManager].imageCache;
//    cache.config.maxCacheAge = 7 * 24 * 60 *60;       // 默认是一周
//    cache.config.maxCacheSize = 0;                    // 默认不限制缓存大小

    // 高德地图
    [AMapServices sharedServices].apiKey = EFAGlobalAMapAppKey;
    
    // HighCharts图表
    [HIChartView preload];
    
    // 融云初始化
//    [[RCIMClient sharedRCIMClient] initWithAppKey:EFAGlobalRongCloudAppKey]; //20190620注释掉
//    // 融云用户信息的代理
//    [RCIM sharedRCIM].userInfoDataSource = self;
    // 融云接收消息的代理
//    [[RCIMClient sharedRCIMClient] setReceiveMessageDelegate:self object:nil];//20190620注释掉
    // 融云IM上线
//    [[EFAModel sharedInstance] rongCloudOnLine];//20190620注释掉
    // 融云推送
    /**
     * 推送处理1
     */
//    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {//20190620注释掉
//        //注册推送, 用于iOS8以及iOS8之后的系统
//        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge |
//                                                                                             UIUserNotificationTypeSound |
//                                                                                             UIUserNotificationTypeAlert)
//                                                                                 categories:nil];
//        [application registerUserNotificationSettings:settings];
//    }
    
//    // 向微信注册
//    [WXApi registerApp:KABGlobalWeChatAppId];
    
    
    
    //个推配置开始
    // Override point for customization after application launch.
    
    //     [ GTSdk ]：是否允许APP后台运行
    [GeTuiSdk runBackgroundEnable:YES];
    
    // [ GTSdk ]：是否运行电子围栏Lbs功能和是否SDK主动请求用户定位
    //    [GeTuiSdk lbsLocationEnable:YES andUserVerify:YES];
    
    // [ GTSdk ]：自定义渠道
        [GeTuiSdk setChannelId:@"GT-Channel"];
    
    // [ GTSdk ]：使用APPID/APPKEY/APPSECRENT创建个推实例
    [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self];
    
    // 注册APNs - custom method - 开发者自定义的方法
    [self registerRemoteNotification];
    
    // 注册VOIP
    [self voipRegistration];
    //个推配置开始结束
    
    

    // 极光推送
    //Required
    //notice: 3.0.0及以后版本注册可以这样写，也可以继续用之前的注册方式
    JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
    entity.types = JPAuthorizationOptionAlert | JPAuthorizationOptionBadge | JPAuthorizationOptionSound;
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
        // 可以添加自定义categories
        // NSSet<UNNotificationCategory *> *categories for iOS10 or later
        // NSSet<UIUserNotificationCategory *> *categories for iOS8 and iOS9
    }
    [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
    // Required
    // init Push
    // notice: 2.1.5版本的SDK新增的注册方法，改成可上报IDFA，如果没有使用IDFA直接传nil
    // 如需继续使用pushConfig.plist文件声明appKey等配置内容，请依旧使用[JPUSHService setupWithOption:launchOptions]方式初始化。
    [JPUSHService setupWithOption:launchOptions appKey:EFAGlobalJPushAppKey
                          channel:@"App Store"
                 apsForProduction:1
            advertisingIdentifier:nil];
    
//    //清空icon图标的上的消息数量标识
//    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
//    // 清空通知栏的推送通知
//    [JPUSHService removeNotification:nil];
    
    // KSPhotoBrowser
    [KSPhotoBrowser setImageManagerClass:[KSSDImageManager class]];
}

#pragma mark - 检查是否审核
- (void)checkIosReview {
    NSString *buildStr = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleVersion"];
    NSDictionary *parameters = @{@"efairyiosbuildid_build_id" : buildStr};
    
    [[XDAFNetworking sharedInstance] GET:[ApiManager apiIosReleaseCheck] parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"请求iOS审核成功:%@", responseObject);
        if ([responseObject[EFAGlobalJsonKeyErrCode] integerValue] == 200) {
            self.isReview = [responseObject[EFAGlobalJsonKeyResult][@"efairyiosbuildid_is_checking"] boolValue];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"请求ios审核失败：%@", error);
    }];
}

#pragma mark - 推送处理
- (void)handlePushWithUserInfo:(NSDictionary *)userInfo {
    //清空icon图标的上的消息数量标识
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
    // 清空通知栏的推送通知
    [JPUSHService removeNotification:nil];
    
    // 目前只处理efairy本身的消息推送
    if (userInfo[@"efairy"]) {
        self.pushDictionary = userInfo;
        NSLog(@"收到极光推送 = %@", userInfo);
        [[NSNotificationCenter defaultCenter] postNotificationName:EFAGlobalNotiPushProcess object:nil userInfo:nil];
    }
}



+(NSString *) dbPath{
    //获取数据库路径
    NSArray *documentArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentPath = [documentArr firstObject];
    // crylown.db 为数据库的名字
    NSString *path = [NSString stringWithFormat:@"%@/getuimsg.db",documentPath];
    return path;
}



-(void) createDB{
    //创建数据库
    int databaseResult = sqlite3_open([[AppDelegate dbPath] UTF8String], &database);
    if (databaseResult != SQLITE_OK) {
        NSLog(@"创建／打开数据库失败,%d",databaseResult);
    }else{
        [self createTable];
    }
}

-(void) createTable{
    char *error;
    //    建表格式: create table if not exists 表名 (列名 类型,....)    注: 如需生成默认增加的id: id integer primary key autoincrement
//     以下是需要创建的字段
//    id
//    efairymsg_from_id; //消息发起者（可能是设备或用户）
//    userId;
//    efairydevice_name;//设备名称
//    isSelected = false;
//    efairymsg_add_time;//消息生成时间
//    msgAddTime;//消息生成时间时间戳手动添加
//    efairymsg_class;
//    efairymsg_sub_class;
//    efairymsg_id; // 聊天编号
//    efairymsg_time; // 消息生成时间
//    efairymsg_content; // 消息主体，
//    efairymsg_msgtype;// 消息类型，0-不需要处理 1-需要处理
//    efairymsg_ishandle;// 是否已处理，0-未处理 1-已处理
//    efairymsg_to_id;// 消息接受者
//    efairymsgText;//消息内容
//    isRead;//是否已读 0未读，1已读 需要手动设置
//    efairydevice_id;
    
    const char *createTable = "create table if not exists gtmessage(id char primary key ,efairymsg_from_id text,userId text not null,efairydevice_name text,efairymsg_add_time text,msgAddTime integer,efairymsg_class text,efairymsg_sub_class text,efairymsg_id integer,efairymsg_time text,efairymsg_content text,efairymsg_msgtype integer,efairymsg_ishandle integer,efairymsg_to_id text,isRead integer,efairydevice_id integer)";
    int tableResult = sqlite3_exec(database, createTable, NULL, NULL, &error);
    if (tableResult != SQLITE_OK) {
        NSLog(@"创建表失败:%s",error);
    }
}

-(void)insertOrUpdate:(EFAMsgIMItem *)item{
    // 对SQL语句执行预编译
//    int qlite3_prepare(database, const char *sql,int byte, stmt,const char **tail);
    
    //   sql语句格式: insert into 表名 (列名)values(值)
    
    if(item == nil){
        return;
    }
    sqlite3_stmt *stmt;
//    NSInteger curUserId = [EFAModel sharedInstance].loginInfo.user_info.efairyuser_id;
//    NSString *userId = [NSString stringWithFormat:@"%ld",curUserId];
    const char *mid = [item.msgId UTF8String];
    const char *selectByIdSQL = "select * from gtmessage where id = ?";
    int selectResult = sqlite3_prepare_v2(database, selectByIdSQL, -1, &stmt, nil);
    BOOL isHaveData = NO;
    if (selectResult == SQLITE_OK) {
        sqlite3_bind_text(stmt,1,mid,-1,NULL);
        while(sqlite3_step(stmt) == SQLITE_ROW){
            isHaveData = YES;
            break;
        }
    }
    
    if(isHaveData){
        const char *updateSQL = "update gtmessage set efairymsg_from_id = ?,userId = ?,efairydevice_name = ?,efairymsg_add_time = ?,msgAddTime = ?,efairymsg_class = ?,efairymsg_sub_class = ?,efairymsg_id = ?,efairymsg_time = ?,efairymsg_content = ?,efairymsg_msgtype = ?,efairymsg_ishandle = ?,efairymsg_to_id = ?,isRead = ?,efairydevice_id = ? where id = ?";
        int insertResult = sqlite3_prepare_v2(database, updateSQL, -1, &stmt, nil);
        if (insertResult == SQLITE_OK) {
            sqlite3_bind_text(stmt, 1,  [item.efairymsg_from_id UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 2,  [item.userId UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 3,  [item.efairydevice_name UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 4,  [item.efairymsg_add_time UTF8String],-1,NULL);
            sqlite3_bind_int64(stmt, 5, item.msgAddTime);
            sqlite3_bind_text(stmt, 6,  [item.efairymsg_class UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 7,  [item.efairymsg_sub_class UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 8,  [item.efairymsg_id UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 9, [item.efairymsg_time UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 10, [item.efairymsg_content UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 11, [item.efairymsg_msgtype UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 12, [item.efairymsg_ishandle UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 13, [item.efairymsg_to_id UTF8String],-1,NULL);
            sqlite3_bind_int(stmt, 14, 0);
            sqlite3_bind_text(stmt, 15, [item.efairydevice_id UTF8String],-1,NULL);
             sqlite3_bind_text(stmt, 16, mid, -1, NULL);
        }else{
            NSLog(@"修改数据错误");
        }
    }else{
        const char *insertSQL = "insert into gtmessage (id,efairymsg_from_id,userId,efairydevice_name,efairymsg_add_time,msgAddTime,efairymsg_class,efairymsg_sub_class,efairymsg_id,efairymsg_time,efairymsg_content,efairymsg_msgtype,efairymsg_ishandle,efairymsg_to_id,isRead,efairydevice_id)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        int insertResult = sqlite3_prepare_v2(database, insertSQL, -1, &stmt, nil);
        
        if (insertResult == SQLITE_OK) {
            sqlite3_bind_text(stmt, 1, mid, -1, NULL);
            sqlite3_bind_text(stmt, 2,  [item.efairymsg_from_id UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 3,  [item.userId UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 4,  [item.efairydevice_name UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 5,  [item.efairymsg_add_time UTF8String],-1,NULL);
            sqlite3_bind_int64(stmt, 6, (long)item.msgAddTime);
            sqlite3_bind_text(stmt, 7,  [item.efairymsg_class UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 8,  [item.efairymsg_sub_class UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 9,  [item.efairymsg_id UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 10, [item.efairymsg_time UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 11, [item.efairymsg_content UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 12, [item.efairymsg_msgtype UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 13, [item.efairymsg_ishandle UTF8String],-1,NULL);
            sqlite3_bind_text(stmt, 14, [item.efairymsg_to_id UTF8String],-1,NULL);
            sqlite3_bind_int(stmt, 15, 0);
            sqlite3_bind_text(stmt, 16, [item.efairydevice_id UTF8String],-1,NULL);
        }else{
            NSLog(@"插入数据错误");
        }
    }
    //执行sql语句
    sqlite3_step(stmt);
    sqlite3_finalize(stmt);
}







-(int) getNotReadMsgNum{
    // 获取未读消息数
    NSInteger uid = [EFAModel sharedInstance].loginInfo.user_info.efairyuser_id;
    int count = 0;
    sqlite3_stmt *stmt;
    const char *selectSQL = "select count(*) from gtmessage where isRead = ? and userId = ? and msgAddTime >= ?";
    int updateResult = sqlite3_prepare_v2(database, selectSQL, -1, &stmt, nil);
    if (updateResult != SQLITE_OK) {
        NSLog(@"获取信息总数失败,%d",updateResult);
    }
    else{
        sqlite3_bind_int(stmt,1,0);
         sqlite3_bind_text(stmt,2,[[NSString stringWithFormat:@"%ld",uid]UTF8String],-1,NULL);
         sqlite3_bind_int64(stmt,3,[AppDelegate getNowTimeTimestamp]-(6*24*60*60*1000));
        while (sqlite3_step(stmt) == SQLITE_ROW) {
         count = (int)sqlite3_column_int64(stmt, 0);
          NSLog(@"未读信息,%d",count);
        }
//        count = sqlite3_data_count(stmt);
//        int count = sqlite3_data_count(stmt);
    }
     sqlite3_finalize(stmt);
    return count;
}


+(long)getNowTimeTimestamp{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss SSS"]; // 设置想要的格式，hh与HH的区别:分别表示12小时制,24小时制
    //设置时区,这一点对时间的处理有时很重要
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
    [formatter setTimeZone:timeZone];
    NSDate *datenow = [NSDate date];
    long timestamp = (long)[datenow timeIntervalSince1970]*1000;
    return timestamp;
}

@end
